import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { AnnouncementEntity } from "../entities/announcement.entity";

@Injectable()
export class AnnouncementService {
  constructor(
    @InjectRepository(AnnouncementEntity)
    private announcementRepository: Repository<AnnouncementEntity>
  ) {}

  /**
   * 获取公告列表（分页）
   * @param pageNum 页码（从0开始）
   * @param pageSize 每页数量
   * @returns 公告列表
   */
  async getAnnouncementList(pageNum: number = 0, pageSize: number = 20) {
    try {
      const [announcements, total] = await this.announcementRepository
        .createQueryBuilder("announcement")
        .where("announcement.isActive = :isActive", { isActive: 1 })
        .andWhere("announcement.state = :state", { state: 2 }) // 只返回已发布的公告
        .orderBy("announcement.priority", "DESC")
        .addOrderBy("announcement.publishTime", "DESC")
        .skip(pageNum * pageSize)
        .take(pageSize)
        .getManyAndCount();

      // 转换为客户端期望的格式
      const list = announcements.map((announcement) => ({
        id: announcement.id,
        title: announcement.title,
        content: announcement.content,
        createTime: announcement.publishTime.toISOString().replace("T", " ").replace("Z", ".0"),
        state: announcement.state,
        priority: announcement.priority,
        publisher: announcement.publisher,
        viewCount: announcement.viewCount,
      }));

      return {
        list,
        total,
        pageNum,
        pageSize,
        totalPages: Math.ceil(total / pageSize),
      };
    } catch (error) {
      console.error("获取公告列表失败:", error);
      throw new Error("获取公告列表失败");
    }
  }

  /**
   * 根据ID获取公告详情
   * @param id 公告ID
   * @returns 公告详情
   */
  async getAnnouncementById(id: number) {
    try {
      const announcement = await this.announcementRepository.findOne({
        where: { id, isActive: 1 },
      });

      if (!announcement) {
        throw new Error("公告不存在");
      }

      // 增加浏览次数
      await this.announcementRepository.update(id, {
        viewCount: announcement.viewCount + 1,
      });

      return {
        id: announcement.id,
        title: announcement.title,
        content: announcement.content,
        createTime: announcement.publishTime.toISOString().replace("T", " ").replace("Z", ".0"),
        state: announcement.state,
        priority: announcement.priority,
        publisher: announcement.publisher,
        viewCount: announcement.viewCount + 1,
        publishTime: announcement.publishTime,
        offlineTime: announcement.offlineTime,
      };
    } catch (error) {
      console.error("获取公告详情失败:", error);
      throw new Error("获取公告详情失败");
    }
  }

  /**
   * 创建新公告
   * @param announcementData 公告数据
   * @returns 创建的公告
   */
  async createAnnouncement(announcementData: {
    title: string;
    content: string;
    state?: number;
    priority?: number;
    publisher?: string;
    publishTime?: Date;
  }) {
    try {
      const announcement = this.announcementRepository.create({
        ...announcementData,
        state: announcementData.state || 1,
        priority: announcementData.priority || 0,
        publishTime: announcementData.publishTime || new Date(),
        viewCount: 0,
        isActive: 1,
      });

      const savedAnnouncement = await this.announcementRepository.save(announcement);
      return savedAnnouncement;
    } catch (error) {
      console.error("创建公告失败:", error);
      throw new Error("创建公告失败");
    }
  }

  /**
   * 更新公告
   * @param id 公告ID
   * @param updateData 更新数据
   * @returns 更新后的公告
   */
  async updateAnnouncement(
    id: number,
    updateData: Partial<{
      title: string;
      content: string;
      state: number;
      priority: number;
      publisher: string;
      publishTime: Date;
      offlineTime: Date;
    }>
  ) {
    try {
      const announcement = await this.announcementRepository.findOne({
        where: { id, isActive: 1 },
      });

      if (!announcement) {
        throw new Error("公告不存在");
      }

      await this.announcementRepository.update(id, updateData);
      return await this.getAnnouncementById(id);
    } catch (error) {
      console.error("更新公告失败:", error);
      throw new Error("更新公告失败");
    }
  }

  /**
   * 删除公告（软删除）
   * @param id 公告ID
   * @returns 删除结果
   */
  async deleteAnnouncement(id: number) {
    try {
      const announcement = await this.announcementRepository.findOne({
        where: { id, isActive: 1 },
      });

      if (!announcement) {
        throw new Error("公告不存在");
      }

      await this.announcementRepository.update(id, { isActive: 0 });
      return { success: true, message: "公告删除成功" };
    } catch (error) {
      console.error("删除公告失败:", error);
      throw new Error("删除公告失败");
    }
  }

  /**
   * 发布公告
   * @param id 公告ID
   * @returns 发布结果
   */
  async publishAnnouncement(id: number) {
    try {
      const announcement = await this.announcementRepository.findOne({
        where: { id, isActive: 1 },
      });

      if (!announcement) {
        throw new Error("公告不存在");
      }

      await this.announcementRepository.update(id, {
        state: 2,
        publishTime: new Date(),
      });

      return { success: true, message: "公告发布成功" };
    } catch (error) {
      console.error("发布公告失败:", error);
      throw new Error("发布公告失败");
    }
  }

  /**
   * 下线公告
   * @param id 公告ID
   * @returns 下线结果
   */
  async offlineAnnouncement(id: number) {
    try {
      const announcement = await this.announcementRepository.findOne({
        where: { id, isActive: 1 },
      });

      if (!announcement) {
        throw new Error("公告不存在");
      }

      await this.announcementRepository.update(id, {
        state: 3,
        offlineTime: new Date(),
      });

      return { success: true, message: "公告下线成功" };
    } catch (error) {
      console.error("下线公告失败:", error);
      throw new Error("下线公告失败");
    }
  }

  /**
   * 获取重要公告
   * @param limit 数量限制
   * @returns 重要公告列表
   */
  async getImportantAnnouncements(limit: number = 5) {
    try {
      const announcements = await this.announcementRepository
        .createQueryBuilder("announcement")
        .where("announcement.isActive = :isActive", { isActive: 1 })
        .andWhere("announcement.state = :state", { state: 2 })
        .andWhere("announcement.priority > :priority", { priority: 0 })
        .orderBy("announcement.priority", "DESC")
        .addOrderBy("announcement.publishTime", "DESC")
        .take(limit)
        .getMany();

      return announcements.map((announcement) => ({
        id: announcement.id,
        title: announcement.title,
        content: announcement.content,
        createTime: announcement.publishTime.toISOString().replace("T", " ").replace("Z", ".0"),
        state: announcement.state,
        priority: announcement.priority,
        publisher: announcement.publisher,
        viewCount: announcement.viewCount,
      }));
    } catch (error) {
      console.error("获取重要公告失败:", error);
      throw new Error("获取重要公告失败");
    }
  }

  /**
   * 搜索公告
   * @param keyword 搜索关键词
   * @param pageNum 页码
   * @param pageSize 每页数量
   * @returns 搜索结果
   */
  async searchAnnouncements(
    keyword: string,
    pageNum: number = 0,
    pageSize: number = 20
  ) {
    try {
      const [announcements, total] = await this.announcementRepository
        .createQueryBuilder("announcement")
        .where("announcement.isActive = :isActive", { isActive: 1 })
        .andWhere("announcement.state = :state", { state: 2 })
        .andWhere(
          "(announcement.title LIKE :keyword OR announcement.content LIKE :keyword)",
          { keyword: `%${keyword}%` }
        )
        .orderBy("announcement.publishTime", "DESC")
        .skip(pageNum * pageSize)
        .take(pageSize)
        .getManyAndCount();

      const list = announcements.map((announcement) => ({
        id: announcement.id,
        title: announcement.title,
        content: announcement.content,
        createTime: announcement.publishTime.toISOString().replace("T", " ").replace("Z", ".0"),
        state: announcement.state,
        priority: announcement.priority,
        publisher: announcement.publisher,
        viewCount: announcement.viewCount,
      }));

      return {
        list,
        total,
        pageNum,
        pageSize,
        totalPages: Math.ceil(total / pageSize),
      };
    } catch (error) {
      console.error("搜索公告失败:", error);
      throw new Error("搜索公告失败");
    }
  }

  /**
   * 获取公告统计信息
   * @returns 统计信息
   */
  async getAnnouncementStats() {
    try {
      const total = await this.announcementRepository.count({
        where: { isActive: 1 },
      });

      const published = await this.announcementRepository.count({
        where: { isActive: 1, state: 2 },
      });

      const draft = await this.announcementRepository.count({
        where: { isActive: 1, state: 1 },
      });

      const offline = await this.announcementRepository.count({
        where: { isActive: 1, state: 3 },
      });

      const important = await this.announcementRepository.count({
        where: { isActive: 1, state: 2, priority: 2 },
      });

      return {
        total,
        published,
        draft,
        offline,
        important,
      };
    } catch (error) {
      console.error("获取公告统计失败:", error);
      throw new Error("获取公告统计失败");
    }
  }
} 